package cn.shengchao.controler.wecom;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.shengchao.base.lock.DistributedLock;
import cn.shengchao.base.lock.ZLock;
import cn.shengchao.examstar.rpc.wecom.cs.WeComLockCs;
import cn.shengchao.examstar.rpc.wecom.dto.UserContactMeQrcodeCheckVo;
import cn.shengchao.qywx.infrastrure.po.*;
import cn.shengchao.qywx.infrastrure.service.*;
import cn.shengchao.rule.base.*;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @program: examstarapi
 * @description: 联系我的加载器
 * @author: Xiong weiqiang
 * @create: 2025-04-15 10:13
 */
@Component
public class QywxContactMeLoader {
    @Autowired
    QywxSysCsGroupUserbindService qywxSysCsGroupUserbindService;
    @Autowired
    QywxCustomerQrcodeLockerService qywxCustomerQrcodeLockerService;
    @Autowired
    QywxUserSysbindService qywxUserSysbindService;
    @Autowired
    QywxUserServiceInviteService qywxUserServiceInviteService;
    @Autowired
    QywxUserService qywxUserService;
    @Autowired
    DistributedLock distributedLock;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    /**
     *  获取平台联系我的二维码
     * @param reqUserId
     * @return
     */
    public ContactMeResult getPlatFormContactMe(Long reqUserId){
        String defaultUserId=getGroupUserListTurnUser("0");
        String defaultState=getGroupQrCodeState(0L);
        Object qywxUserQrcode=fetchQrCodeByLock(defaultUserId,defaultState);
        return ContactMeResult.builder().isMatch(true).groupId(0L).state(defaultState).qywxUserQrcode(qywxUserQrcode.toString()).build();
    }

    /**
     * 匹配而且有码的返回
     * @param conditionGroup
     * @param reqUserId
     * @return
     */
    @Transactional
    public ContactMeResult getContactMe(ConditionGroup conditionGroup,Long reqUserId){
        if (conditionGroup!=null){
            IAction action=conditionGroup.getAction();
            String state=getGroupQrCodeState(conditionGroup.getGroupId());
            if (action.getActionType()== ActionType.SPECIFIC_USER){
                //指定用户
                String assignUserId=action.getActionValue();
                Object qywxUserQrcode=fetchQrCodeByLock(assignUserId,state);
                if (qywxUserQrcode==null){
                    return ContactMeResult.builder().isMatch(false).groupId(conditionGroup.getGroupId()).message("指定用户"+reqUserId+"匹配企微号失败:"+assignUserId+"没找到二维码").build();
                }else {
                    saveQywxUserQrcodeLoader(reqUserId,state,assignUserId,qywxUserQrcode.toString());
                    return ContactMeResult.builder().isMatch(true).groupId(conditionGroup.getGroupId()).qywxUserQrcode(qywxUserQrcode.toString()).build();
                }
            }else if (action.getActionType()== ActionType.CUSTOMER_GROUP){
                //客服组分配
                String userId=getGroupUserListTurnUser(action.getActionValue());
                if (StrUtil.isNotBlank(userId)){
                    Object qywxUserQrcode=fetchQrCodeByLock(userId,state);
                    if (qywxUserQrcode==null){
                        return ContactMeResult.builder().isMatch(false).groupId(conditionGroup.getGroupId()).message("客服组"+action.getActionValue()+"匹配企微号失败:"+userId+"没找到二维码").build();
                    }else {
                        saveQywxUserQrcodeLoader(reqUserId,state,userId,qywxUserQrcode.toString());
                        return ContactMeResult.builder().isMatch(true).groupId(conditionGroup.getGroupId()).qywxUserQrcode(qywxUserQrcode.toString()).build();
                    }
                }else {
                    return ContactMeResult.builder().isMatch(false).groupId(conditionGroup.getGroupId()).message("客服组"+action.getActionValue()+"匹配企微号失败:"+userId+"没找到客服组人员").build();
                }
            }else if (action.getActionType()== ActionType.INVITER){
                UserContactMeQrcodeCheckVo userContactMeQrcodeCheckVo=qywxUserServiceInviteService.queryCpUserCheckVo(reqUserId);

                if (userContactMeQrcodeCheckVo==null){
                    System.out.println("邀请所属null：没有邀请指定");
                    return ContactMeResult.builder().isMatch(false).groupId(conditionGroup.getGroupId()).message("邀请所属："+action.getActionValue()).build();
                }else if (userContactMeQrcodeCheckVo.getStatus()!=null&&userContactMeQrcodeCheckVo.getStatus()<=1){
                    List<QywxUserSysbind> qywxUserSysbindList=qywxUserSysbindService.list(
                            Wrappers.lambdaQuery(QywxUserSysbind.class).eq(QywxUserSysbind::getSysUserId,userContactMeQrcodeCheckVo.getServiceUserId())
                    );
                    if (CollUtil.isNotEmpty(qywxUserSysbindList)){
                        List<String> cpUserIdList=qywxUserSysbindList.stream().map(QywxUserSysbind::getQywxUserId).toList();
                        if (!cpUserIdList.contains(userContactMeQrcodeCheckVo.getServiceCpUserId())){
                            System.out.println("再次判断cpUserId是否是原本的绑定关系："+userContactMeQrcodeCheckVo.getServiceCpUserId());
                            //如果变化就作废
                            qywxCustomerQrcodeLockerService.update(
                                    Wrappers.lambdaUpdate(QywxCustomerQrcodeLocker.class).eq(QywxCustomerQrcodeLocker::getUserId,reqUserId)
                                            .eq(QywxCustomerQrcodeLocker::getQrState,state)
                                            .eq(QywxCustomerQrcodeLocker::getLockStatus,1)
                                            .eq(QywxCustomerQrcodeLocker::getRuleUserId,userContactMeQrcodeCheckVo.getServiceCpUserId())
                                            .set(QywxCustomerQrcodeLocker::getLockStatus,2)
                            );
                            //出码，同时更新关联企微好
                            userContactMeQrcodeCheckVo.setStatus(0);

                            userContactMeQrcodeCheckVo.setServiceCpUserId(cpUserIdList.getFirst());
                            Object qywxUserQrcode=fetchQrCodeByLock(userContactMeQrcodeCheckVo.getServiceCpUserId(),state);
                            if (qywxUserQrcode==null){
                                return ContactMeResult.builder().isMatch(false).groupId(conditionGroup.getGroupId()).message("邀请所属换用户找不到码："+userContactMeQrcodeCheckVo.getServiceCpUserId()).build();
                            }
                            userContactMeQrcodeCheckVo.setServiceCpQrcode(qywxUserQrcode.toString());
                            System.out.println("再次判断cpUserId是否是原本的绑定关系不符重设："+userContactMeQrcodeCheckVo.getServiceCpUserId());
                        }

                    }else {
                        System.out.println("邀请所属原用户绑定企微改动不符1："+userContactMeQrcodeCheckVo.getServiceCpUserId());
                        return ContactMeResult.builder().isMatch(false).groupId(conditionGroup.getGroupId()).message("邀请所属原用户绑定企微改动不符："+action.getActionValue()).build();
                    }
                    if (userContactMeQrcodeCheckVo.getStatus()==0){
                        //更改邀请，补上企微号
                        qywxUserServiceInviteService.update(Wrappers.lambdaUpdate(QywxUserServiceInvite.class)
                                .eq(QywxUserServiceInvite::getUserId,reqUserId).eq(QywxUserServiceInvite::getDataStatus,0)
                                .set(QywxUserServiceInvite::getServiceCpUserId,userContactMeQrcodeCheckVo.getServiceCpUserId())
                        );
                    }
                    //锁码
                    saveQywxUserQrcodeLoader(reqUserId,state,userContactMeQrcodeCheckVo.getServiceCpUserId(),userContactMeQrcodeCheckVo.getServiceCpQrcode());
                    System.out.println("邀请所属1："+JSONUtil.toJsonStr(userContactMeQrcodeCheckVo));
                    //匹配邀请所属
                    return ContactMeResult.builder().isMatch(true).groupId(conditionGroup.getGroupId()).qywxUserQrcode(userContactMeQrcodeCheckVo.getServiceCpQrcode()).build();
                }else {
                    //2,匹配上级
                    System.out.println("邀请所属2："+JSONUtil.toJsonStr(userContactMeQrcodeCheckVo));
                    return ContactMeResult.builder().isMatch(true).groupId(conditionGroup.getGroupId()).qywxUserQrcode(userContactMeQrcodeCheckVo.getDistributeCpUserQrcode()).build();
                }
            }else{
                System.out.println("执行目标：匹配失败");
                return getPlatFormContactMe(reqUserId);
            }
        }else {
            return getPlatFormContactMe(reqUserId);
        }
    }

//    /**
//     * 邀请关系从分销的邀请关系表获取
//     * @param actionValue
//     * @return
//     */
//    private List<DistributeNodeInfo> getInviterUserId(String actionValue){
//        List<DistributeNodeInfo> distributeNodeInfos=null;
//        //获取邀请人
//        List<DistributeUserInvite> distributeUserInvites=distributeUserInviteService.list(Wrappers.lambdaQuery(DistributeUserInvite.class)
//                .eq(DistributeUserInvite::getUserId, actionValue).eq(DistributeUserInvite::getDataStatus, DistributeDataStatusEnum.STATUS_CURT.getStatus()));
//        if (distributeUserInvites!=null&&distributeUserInvites.size()==1){
//            Long userId=distributeUserInvites.get(0).getInviteUserId();
//            List<Long> userIds=distributeNodeRoleChainService.selectContentChainUserIds(userId);
//            System.out.print("邀请人"+actionValue+"分销链："+ JSONUtil.toJsonStr(userIds));
//            distributeNodeInfos=distributeNodeInfoService.list(Wrappers.lambdaQuery(DistributeNodeInfo.class)
//                            .eq(DistributeNodeInfo::getDistributeType, DistributeTypeEnum.TYPE_SALE.getType())
//                            .eq(DistributeNodeInfo::getDataStatus, DistributeDataStatusEnum.STATUS_CURT.getStatus())
//                    .in(DistributeNodeInfo::getUserId,  userIds));
//            if (CollUtil.isNotEmpty(distributeNodeInfos)){
//                return distributeNodeInfos.stream().filter(a->!a.getDistributeRoleCode().equals(DistributeSaleRoleEnum.ROLE_MKMG.getCode())).toList();
//            }
//            return distributeNodeInfoService.list(Wrappers.lambdaQuery(DistributeNodeInfo.class).eq(DistributeNodeInfo::getUserId,  userIds));
//        }
//        return null;
//    }
    /**
     * 轮询邀请人的用户id
     * @param inviterUserId
     * @return
     */
    private String getInviterUserListTurnUser(String inviterUserId){
        if (redisTemplate.hasKey(WeComLockCs.getRedisKeyForInviterGroupUsers(inviterUserId))){
            //右边取出第一个元素，再从左边放回
            Object userId=redisTemplate.opsForList().rightPop(WeComLockCs.getRedisKeyForInviterGroupUsers(inviterUserId));
            redisTemplate.opsForList().leftPush(WeComLockCs.getRedisKeyForInviterGroupUsers(inviterUserId),userId);
            System.out.print("邀请人"+inviterUserId+"邀请组："+inviterUserId+"轮询分组客服用户id："+userId);
            return userId.toString();
        }else{
            List<QywxUserSysbind> qywxUserSysbindList=qywxUserSysbindService.list(
                    Wrappers.lambdaQuery(QywxUserSysbind.class).eq(QywxUserSysbind::getSysUserId,inviterUserId)
            );
            if (CollUtil.isNotEmpty(qywxUserSysbindList)){
                for (QywxUserSysbind qywxUserSysbind:qywxUserSysbindList){
                    redisTemplate.opsForList().leftPush(WeComLockCs.getRedisKeyForInviterGroupUsers(inviterUserId),qywxUserSysbind.getQywxUserId());
                }
                return getInviterUserListTurnUser(inviterUserId);
            }else{
                return getGroupUserListTurnUser("0");
            }
        }
    }
    /**
     * 轮询分组客服的用户id
     * @param groupId
     * @return
     */
    private String getGroupUserListTurnUser(String groupId){
        if (redisTemplate.hasKey(WeComLockCs.getRedisKeyForCsGroupUsers(groupId))){
            //右边取出第一个元素，再从左边放回
            Object userId=redisTemplate.opsForList().rightPop(WeComLockCs.getRedisKeyForCsGroupUsers(groupId));
            redisTemplate.opsForList().leftPush(WeComLockCs.getRedisKeyForCsGroupUsers(groupId),userId);
            System.out.print("规则组："+groupId+"轮询分组客服用户id："+userId);
            return userId.toString();
        }else{
            List<QywxSysCsGroupUserbind> qywxSysCsGroupUserbindList=qywxSysCsGroupUserbindService.list(
                    Wrappers.lambdaQuery(QywxSysCsGroupUserbind.class).eq(QywxSysCsGroupUserbind::getCsGroupId,groupId));
            if (CollUtil.isNotEmpty(qywxSysCsGroupUserbindList)){
                for (QywxSysCsGroupUserbind qywxSysCsGroupUserbind:qywxSysCsGroupUserbindList){
                    redisTemplate.opsForList().leftPush(WeComLockCs.getRedisKeyForCsGroupUsers(groupId),qywxSysCsGroupUserbind.getQywxUserId());
                }
                return getGroupUserListTurnUser(groupId);
            }else{
                return getGroupUserListTurnUser("0");
            }
        }
    }
    /**
     * 获取联系我二维码(分布式锁，避免没有的时候重复请求企微生成同样渠道和用户的二维码)
     * @param weComUserId(企业微信id)
     * @param state
     * @return
     */
    private Object fetchQrCodeByLock(String weComUserId,String state){
        String lockKey= WeComLockCs.getLockKeyForUserSingleConcatMe(weComUserId,state);
        String redisKey= WeComLockCs.getRedisKeyForUserSingleConcatMe(weComUserId,state);
        if (redisTemplate.hasKey(redisKey)){
            return redisTemplate.opsForValue().get(redisKey);
        }else {
            ZLock lock=null;
            try {
                lock=distributedLock.lock(lockKey, 3000, TimeUnit.MILLISECONDS);
                List<QywxUser> qywxUserList=qywxUserService.list(Wrappers.lambdaQuery(QywxUser.class).eq(QywxUser::getUserId,weComUserId)
                                .eq(QywxUser::getStatus,"1")
                        .eq(QywxUser::getQrCodeStatus,1).isNotNull(QywxUser::getQrCodeUrl));
                if (CollUtil.isNotEmpty(qywxUserList)){
                    redisTemplate.opsForValue().set(redisKey,qywxUserList.getFirst().getQrCodeUrl());
                    return redisTemplate.opsForValue().get(redisKey);
                }else {
                    System.out.println("调企微："+state+"，分配用户："+weComUserId);
                    return null;
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }finally {
                if (lock!=null){
                    try {
                        lock.close();
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

    }


    public String getGroupQrCodeState(Long groupId){
        return RuleQrCodeState.RG0.getStatePrefix()+groupId;
    }

    private void saveQywxUserQrcodeLoader(Long reqUserId,String state,String assignUserId,String qrCode){
        long count=qywxCustomerQrcodeLockerService.count(
                Wrappers.lambdaQuery(QywxCustomerQrcodeLocker.class).eq(QywxCustomerQrcodeLocker::getUserId,reqUserId)
                        .eq(QywxCustomerQrcodeLocker::getQrState,state).eq(QywxCustomerQrcodeLocker::getLockStatus,1)
        );
        if (count==0){
            qywxCustomerQrcodeLockerService.save(
                    QywxCustomerQrcodeLocker.builder()
                            .userId(reqUserId)
                            .qrState(state)
                            .ruleUserId(assignUserId)
                            .qrCode(qrCode)
                            .lockStatus(1)
                            .build()
            );
        }
    }
}